package view;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;

import common.Utils;

import model.DrawObject;

public class ViewEllipse extends ViewObject
{
	public ViewEllipse(DrawObject obj, Graphics g)
	{
		super(obj, g);
	}

	public ViewEllipse(DrawObject obj, Graphics2D g2) 
	{
		super(obj, g2);
	}

	@Override
	public void Draw(Graphics g)
	{
		super.Draw(g);
		
		Graphics2D g2 = (Graphics2D)g;
		
		Color c = new Color(dObj.getRed(), dObj.getGreen(), dObj.getBlue());
		g2.setColor(c);
		
		if (dObj.getThickness() == 0)
		{
			g2.fillOval( dObj.getX1(), dObj.getY1(), dObj.getWidth(), dObj.getHeight());
		}
		else
		{
			g2.setStroke( new BasicStroke( (float)dObj.getThickness() ) );
			g2.drawOval( dObj.getX1(), dObj.getY1(), dObj.getWidth(), dObj.getHeight() );
		}
		
		
		// for testing purposes
//		g2.setColor( new Color(0,0,0) );
//		g2.setStroke( new BasicStroke(1) );
//		
//		double inc = 1.0/1000.0;
//		int x, y;
//		for (double t=0; t<=1; t+=inc)
//		{
//			x = pFuncX(t);
//			y = pFuncY(t);
//			g2.drawLine(x, y, x, y);
//		}
//		
//		g2.drawLine(250, 200, 250, 200);
		
	}

	@Override
	public int pFuncX(double t)
	{
		double a = dObj.getWidth()/2;
		double Cx = dObj.getX1() + a - 1;
		
		// x = a*cos(t*2Pi) + Cx
		return  (int)( a * Math.cos(t*Math.PI*2) + Cx );
	}

	@Override
	public int pFuncY(double t)
	{
		double b = dObj.getHeight()/2;
		double Cy = dObj.getY1() + b - 1;
		
		// y = b*sin(t*2Pi) + Cy
		return (int)( b * Math.sin(t*Math.PI*2) + Cy );
	}

	@Override
	public BoundBox getBounds(boolean padded)
	{
		int padding = (padded)? Utils.MIN_DIST : 0;
		
		BoundBox box = new BoundBox();
		box.setX( dObj.getX1() - padding );
		box.setY( dObj.getY1() - padding );
		box.setWidth( dObj.getWidth() + padding*2 - 1 );
		box.setHeight( dObj.getHeight() + padding*2 - 1 );
		
		return box;
	}

	@Override
	public boolean containsPoint(Point p)
	{
		if ( !this.getBounds(true).contains(p) )
			return false;
		
		if ( dObj.getThickness() == 0 )
		{
			if (insideTest(p))
				return true;
			else 
				return false;
		}
		
		int dist = this.distSqToShape(p, 0.0, 0.5);
		if (dist <= Utils.MIN_DIST_SQ) return true;
		
		dist = this.distSqToShape(p, 0.5, 1.0);
		if (dist <= Utils.MIN_DIST_SQ) return true;
		
		return false;
	}
	
	public boolean insideTest(Point p)
	{
		// ((x - Cx)/a)^2 + ((y - Cy)/b)^2 - 1 <= 0
		
		double a = dObj.getWidth()/2;
		double b = dObj.getHeight()/2;
		
		double Cx = dObj.getX1() + a - 1;
		double Cy = dObj.getY1() + b - 1;
		
		double arg1 =  Math.pow((p.x - Cx)/a, 2);
		double arg2 =  Math.pow((p.y - Cy)/b, 2);
		
		return (arg1 + arg2 - 1) <= 0;
	}


	@Override
	public void deltaTranslatePoint(int pointNo, int dx, int dy)
	{
		
		switch (pointNo)
		{
		case 1:
			this.dObj.setX1( dObj.getX1() + dx );
			this.dObj.setY1( dObj.getY1() + dy );
			
			this.dObj.setX4( dObj.getX1() );
			this.dObj.setY2( dObj.getY1() );
			
			this.dObj.setWidth( this.dObj.getX3() - this.dObj.getX1() );
			this.dObj.setHeight( this.dObj.getY3() - this.dObj.getY1() );
			
			break;
		case 2:
			this.dObj.setX2( dObj.getX2() + dx );
			this.dObj.setY2( dObj.getY2() + dy );
			
			this.dObj.setY1( dObj.getY2() );
			this.dObj.setX3( dObj.getX2() );
			
			this.dObj.setWidth( this.dObj.getX2() - this.dObj.getX4() );
			this.dObj.setHeight( this.dObj.getY4() - this.dObj.getY2() );
			
			break;
		case 3:
			this.dObj.setX3( dObj.getX3() + dx );
			this.dObj.setY3( dObj.getY3() + dy );
			
			this.dObj.setY4( dObj.getY3() );
			this.dObj.setX2( dObj.getX3() );
			
			this.dObj.setWidth( this.dObj.getX3() - this.dObj.getX1() );
			this.dObj.setHeight( this.dObj.getY3() - this.dObj.getY1() );
			
			break;
		case 4:
			this.dObj.setX4( dObj.getX4() + dx );
			this.dObj.setY4( dObj.getY4() + dy );
			
			this.dObj.setY3( dObj.getY4() );
			this.dObj.setX1( dObj.getX4() );
			
			this.dObj.setWidth( this.dObj.getX2() - this.dObj.getX4() );
			this.dObj.setHeight( this.dObj.getY4() - this.dObj.getY2() );
			
			break;
		}
	}
	



}
